//
//	File: OyTTFFont.h
//

#ifndef OYTTFFONT_H
#define OYTTFFONT_H

#include <Windows.h>
#include <tchar.h>
#include <d3d9.h>
#include <ft2build.h>
#include FT_FREETYPE_H

#include "..\..\OyRenderer\OyEngine.h"
#include "..\DataStruct\OyDataStruct.h"
#include "..\..\OyMath3D\OyMath3D.h"
#include "OyD3D9FontRender.h"


class OyDirect3D9;
class OySkinManager;

class Oy_TTF_Font
{
public:

	Oy_TTF_Font( FT_Library ftlib, LPDIRECT3DDEVICE9 pDevice, OyDirect3D9 *pOyD3D9 );
	~Oy_TTF_Font(void);

	// load a TTF font from disk file
	bool LoadTTFFontFromDisk(	const char* strname, const char* strpath, 
								int iSize, bool bBold, bool bItalic );
	// unload the TTF font and free all variables
	void UnloadFont(void);

	// is the character cached?
	bool IsCharCached(TCHAR charCode);

	// clear all the cache entries
	void ClearAllCache(void);

	// char pre-cache
	void PreCacheChar(const TCHAR* sText);

	// flush all font vertex buffer
	HRESULT FlushAllVB(void);

	// DEVICE
	void OnDeviceLost(void);
	void OnDeviceReset(void);

	// draw a string
	bool DrawTextInPos(	const TCHAR* sText, float x, float y, DWORD FontColor, DWORD flag,
		float fFontSize, bool bKerning, bool bUnderl );
	bool DwawTextShadowInPos( const TCHAR* sText, float x, float y, DWORD FontColor, DWORD flag,
		float fFontSize, bool bKerning, bool bUnderl );

	// get the font name 
	const char* GetFontName(void) { return m_strFontName; }

	// In typography, kerning is the process of adjusting the spacing 
	// between characters in a proportional font.
	// Kerning adjusts the space between individual letter forms
	// does font face has kerning
	bool IsKerningSupportedByFace() { return m_bHasKerning; }

	// set x scale when rendering
	void SetXScale(float Scale) { m_fXScale = Scale; }

	// set y scale when rendering
	void SetYScale(float Scale) { m_fYScale = Scale; }

	// set x/y scale when rendering
	void SetScale(float Scale) { m_fXScale = m_fYScale = Scale; }

	// set x hotspot when rendering
	void SetXHotspot(float spot) { m_fXHotSpot = spot; }

	// set y hotspot when rendering
	void SetYHotspot(float spot) { m_fYHotSpot = spot; }

	// set x/y hotspot when rendering
	void SetHotspot(float spot) { m_fXHotSpot = m_fYHotSpot = spot; }

	//
	int GetFontHeight() { return m_CharHeight; }

private:
	//Number of spaces in a tab
	static const unsigned int nTabSize = 4;						// "TAB" size
	static const unsigned int nFontNameStrLen = 256;			// Font file name max length
	static const unsigned int mOyFontTextureSize = 256;			// 256*256 pixel texture size
	static const unsigned int INIT_FONTCACHE_ARRAY_NUM = 1024;	// Max 1024 font cache

	char					m_strFontName[nFontNameStrLen];			// font name
	char					m_strFontFilePath[nFontNameStrLen];		// TTF file path


	// Struct for every cached character
	// Finally character is cached in an IND_Surface for rendering
	struct CharCacheNode
	{
		TCHAR				charCode;						// unicode char value
		UINT32				charAdvance;					// advance value

		int					charOffsetX;					// left offset of the glyph in the image
		int					charOffsetY;					// top offset of the glyph in the image

		USHORT				iPrev, iNext;					// prev OR next CacheNode Index (according frequency)
		
	};

	OyArrayStack<CharCacheNode>			m_FontCharCache;		// character cache list
	USHORT								m_CharCacheMap[65536];	// Map of TCHAR => UINT Index in m_FontCharCache List
	OyArrayStack<OyTexture>				m_CharCacheTexture;		// Font cache Texture
	OyArrayStack<OyD3D9_FontBuffer*>	m_FontVB;				// Font Render VB & IB

	USHORT					m_LastCacheIndex;		// Font will be replaced(frequency is low)
	USHORT					m_FirstCacheIndex;		// First Font in Cache(frequency is high)
	int						m_SpaceAdvance;

	OyDirect3D9				*m_pOyD3D9;
	LPDIRECT3DDEVICE9		m_pDevice;
	FT_Library				m_FTLib;				// freetype lib
	FT_Face					m_Face;					// THIS font face
	float					m_fFaceAscender;


	
	int						m_CharWidth;			// current font width
	int						m_CharHeight;			// current font height
	USHORT					m_MaxCharInRow;			// max char num of one row in texture 


	bool					m_bHasKerning;			// font face has kerning
	
	bool					m_bBold;				// bold
	bool					m_bItalic;				// italic
	FT_Matrix				m_matItalic;			// transformation matrix for italic

	float					m_fXScale;				// x scale for bliting
	float					m_fYScale;				// y scale for bliting

	float					m_fXHotSpot;			// x hotspot for bliting
	float					m_fYHotSpot;			// y hotspot for bliting

	DWORD					m_FontShadowColor;		// font shadow color(if font has shadow)

private:
	// cache a single char
	bool _BuildCharCache( TCHAR charCode );

	// render a single char
	bool _RenderChar( TCHAR charCode, float x, float y, DWORD FontColor, 
		DWORD flag, float fFontSize, bool bKerning, bool bUnderl );

	// render glyph to image
	bool _RenderGlyph(FT_Bitmap* Glyph, OyTexture* pFontTexture, USHORT x, USHORT y);

	// advance with space 
	int _GetSpaceAdvance();

	// now not use
	void _DoDrawBorder(float fX_s, float fX_e, float fY, DWORD color, float fFontSize);
};


#endif